package com.tank;

import com.tank.net.Client;
import com.tank.net.msg.BulletNewMsg;

import java.awt.*;
import java.util.Random;
import java.util.UUID;

/**
 * @author CaoBaoYin
 * @since 2021/8/15 22:01
 */
public class Tank {
    private static final int SPEED = 5;
    public final Rectangle rectangle;
    private int x;
    private int y;
    public static final int WIDTH = ResourceManager.goodTankU.getWidth();
    public static final int HEIGHT = ResourceManager.goodTankU.getHeight();

    private UUID id = UUID.randomUUID();//坦克的唯一标识

    private boolean moving = false;

    private DirectionEnum dir;

    private TankFrame tf;

    private boolean living = true;//坦克是否存活

    private GroupEnum groupEnum = GroupEnum.BAD;

    private Random random = new Random();

    public Tank (int x, int y, DirectionEnum dir, GroupEnum groupEnum, TankFrame tf) {
        this.x = x;
        this.y = y;
        this.dir = dir;
        this.groupEnum = groupEnum;
        this.tf = tf;

        rectangle = new Rectangle(x, y, WIDTH, HEIGHT);
    }

    public GroupEnum getGroupEnum() {
        return groupEnum;
    }

    public void setGroupEnum(GroupEnum groupEnum) {
        this.groupEnum = groupEnum;
    }

    public boolean isLiving() {
        return living;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public void paint(Graphics g) {
        Color color = g.getColor();
        g.setColor(Color.RED);
        g.drawString(this.id.toString(), this.x, this.y-10);
        g.setColor(color);

        // 窗口0,0是左上角，横坐标是X，纵坐标是Y，
        switch (dir) {
            case UP:{
                g.drawImage(this.groupEnum == GroupEnum.GOOD ? ResourceManager.goodTankU : ResourceManager.badTankU,this.x, this.y, null);
                break;
            }
            case DOWN:{
                g.drawImage(this.groupEnum == GroupEnum.GOOD ? ResourceManager.goodTankD : ResourceManager.badTankD,this.x, this.y, null);
                break;
            }
            case LEFT:{
                g.drawImage(this.groupEnum == GroupEnum.GOOD ? ResourceManager.goodTankL : ResourceManager.badTankL,this.x, this.y, null);
                break;
            }
            case RIGHT:{
                g.drawImage(this.groupEnum == GroupEnum.GOOD ? ResourceManager.goodTankR : ResourceManager.badTankR,this.x, this.y, null);
                break;
            }
            default:{

            }
        }

        move();
    }

    private void move() {
        if (!moving) return;

        switch (dir) {
            case UP:{
                y -= SPEED;
                break;
            }
            case DOWN:{
                y += SPEED;
                break;
            }
            case LEFT:{
                x -= SPEED;
                break;
            }
            case RIGHT:{
                x += SPEED;
                break;
            }
            default:{

            }
        }

        // 敌方坦克，自动开火，自动转向
        /*if (this.groupEnum == GroupEnum.BAD) {
            if (random.nextInt(100) > 90) this.fire();
            if (random.nextInt(100) > 95) randomDirection();
        }*/

        // 边界检测, 不让坦克开出窗口
        boundsCheck();

        // update rec
        rectangle.x = this.x;
        rectangle.y = this.y;
    }

    private void boundsCheck() {
        if (this.x < 0) this.x = 0;
        if (this.y < 30) this.y = 30;
        if (this.x > TankFrame.GAME_WIDTH - WIDTH) this.x = TankFrame.GAME_WIDTH - WIDTH;
        if (this.y > TankFrame.GAME_HEIGHT - HEIGHT) this.y = TankFrame.GAME_HEIGHT - HEIGHT;
    }

    private void randomDirection() {
        this.dir = DirectionEnum.values()[random.nextInt(4)];
    }

    public DirectionEnum getDir() {
        return dir;
    }

    public void setDir(DirectionEnum dir) {
        this.dir = dir;
    }

    public boolean isMoving() {
        return moving;
    }

    public void setMoving(boolean moving) {
        this.moving = moving;
    }

    public void fire() {
        int bx = 0, by = 0;
        switch (this.dir) {
            case UP: {
                bx = this.x + Tank.WIDTH/2 - Bullet.WIDTH/2;
                by = this.y ;
                break;
            }
            case DOWN: {
                bx = this.x + Tank.WIDTH/2 - Bullet.WIDTH/2;
                by = this.y + Tank.HEIGHT - Bullet.HEIGHT;
                break;
            }
            case LEFT: {
                bx = this.x;
                by = this.y + Tank.HEIGHT/2 - Bullet.HEIGHT/2 ;
                break;
            }
            case RIGHT: {
                bx = this.x + Tank.WIDTH - Bullet.WIDTH;
                by = this.y + Tank.HEIGHT/2 - Bullet.HEIGHT/2 ;
                break;
            }
        }

        Bullet bullet = new Bullet(bx, by, this.dir, this.groupEnum, this.tf);
        tf.bulletList.add(bullet);

        Client.INSTANCE.sendMsg(new BulletNewMsg(bullet, this.id));

        // if(this.groupEnum == GroupEnum.GOOD)
            new Thread(()->new Audio("audio/tank_fire.wav").play()).start();
    }

    public void die() {
        this.living = false;
        int ex = this.x + Tank.WIDTH/2 - Explode.WIDTH/2;
        int ey = this.y + Tank.HEIGHT/2 - Explode.HEIGHT/2;
        this.tf.explodeList.add(new Explode(ex, ey, this.tf));

        if (this.id.equals(TankFrame.INSTANCE.getMainTank().getId())) {
            TankFrame.INSTANCE.exit();
        }
    }

    public UUID getId() {
        return id;
    }

    public void setId(UUID id) {
        this.id = id;
    }
}
